using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Windows.Forms;

/**********************************Simple Tray Icon sample DOTNET 2.0***********************************************
 * This class creates the notification icon that dotnet 2.0 offers.
 * It will be displaying the status of the application with appropiate icons.
 * It will have a contextmenu that enables the user to open the form or exit the application.
 * The form could be used to change settings of the app which in turn are saved in the app.config or some other file.
 * This formless, useless, notification sample does only chane the icon and balloontext.
 * NOTE:Chacker is a Singleton class so it will only allow to be instantiated once, and therefore only one instance.
 * I have done this to prevent more then one icon on the tray and to share data with the form (if any)
 *
 ******************************************************************************************************************/

namespace Skolan
{
    class Checker : IDisposable
    {
        //Checker is a singleton
        private static readonly Checker checker = new Checker();

        //state the sample app could be in
        enum state
        {
            AllStop,
            Run,
            Stop,
            SomeActivity,
            Unknown
        }
        state iconstate = state.AllStop;

        //timer
        bool IsDisposing = false;
        int TimeOut = 10000; //10 sec 
        System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

        //notify icon: prepare the icons we may use in the notification
        NotifyIcon notify;
        System.Drawing.Icon iconstop = new System.Drawing.Icon("STOPSIGN.ICO");
        System.Drawing.Icon icongreen = new System.Drawing.Icon("TRAFFIC4.ICO");
        System.Drawing.Icon iconred = new System.Drawing.Icon("TRAFFIC2.ICO");
        System.Drawing.Icon iconyellow = new System.Drawing.Icon("TRAFFIC3.ICO");
        System.Drawing.Icon iconall = new System.Drawing.Icon("TRAFFIC1.ICO");

        //GUI: the form is not loaded into memory before it used, after use it is removed from memory
        //The notification icon has a contextmenu
        Form1 form;
        bool formPresent=false;
        ContextMenu contextmenu = new ContextMenu();

        /**************************** Singleton *****************************************************************
         * Make the constructor private and create a public method that returns the object reference.
         * The method must be static to be able to be called from different classes at any given moment.
         * The object is created when the first reference is ask for.
         * After that no more instances are created.
         ********************************************************************************************************/
        
        public static Checker GetCheckerObject()
        {
            return checker;
        }

        public int Timeout
        {
            set
            {
                this.TimeOut = value * 1000;
                this.timer.Interval = this.TimeOut;
            }
            get
            {
                return (this.TimeOut / 1000);
            }
        }
        
        private Checker() //singleton so private constructor!
        {
            //create menu
            //popup contextmenu when doubleclicked or when clicked in the menu.
            MenuItem item = new MenuItem("VriServer Control", new EventHandler(notify_DoubleClick));
            contextmenu.MenuItems.Add(item);
            //add a exit submenu item
            item = new MenuItem("Exit", new EventHandler(Menu_OnExit));
            contextmenu.MenuItems.Add(item);
            

            //notifyicon
            notify = new NotifyIcon();
            notify.Icon = iconstop;
            notify.Text = "VriServerManager";
            notify.ContextMenu = contextmenu;
            notify.DoubleClick += new EventHandler(notify_DoubleClick); //show form when double clicked
            notify.Visible = true;

            //timer for sample actions
            timer.Tick += new EventHandler(timer_Tick);
            timer.Interval = 10000;
            timer.Start();
        }

        //you could do some real checking here
        void timer_Tick(object sender, EventArgs e)
        {
            switch (iconstate)
            {
                case state.AllStop:
                    {
                        notify.Icon = iconstop;
                        notify.BalloonTipText = "All Stop";
                        break;
                    }
                case state.Run:
                    {
                        notify.Icon = icongreen;
                        notify.BalloonTipText = "All Running";
                        break;
                    }
                case state.SomeActivity:
                    {
                        notify.Icon = iconyellow;
                        notify.BalloonTipText = "Some Activity";
                        break;
                    }
                case state.Stop:
                    {
                        notify.Icon = iconred;
                        notify.BalloonTipText = "Stop";
                        break;
                    }
                default:
                    {
                        notify.Icon = iconall;
                        notify.BalloonTipText = "Unknown state";
                        break;
                    }
            }
            notify.ShowBalloonTip(1000);
            if (iconstate == state.Unknown)
                iconstate = state.AllStop;
            iconstate++;
        }

        void notify_DoubleClick(object sender, EventArgs e)
        {
            //show the form for settings
            //prevent user from creating more then one form
            if (!formPresent)
            {
                formPresent = true;
                form = new Form1();
                //use close event to reset formpresent boolean
                form.FormClosed += new FormClosedEventHandler(form_FormClosed);
                form.Show();
            }
        }

        void form_FormClosed(object sender, FormClosedEventArgs e)
        {
            formPresent = false;
            form = null;
        }


        ~Checker()
        {
            Dispose();
        }

        public void Dispose()
        {
            if (!IsDisposing)
            {
                timer.Stop();
                IsDisposing = true;
            }
        }

        void Menu_OnExit(Object sender, EventArgs e)
        {
            //be sure to call Application.Exit
            Dispose();
            Application.Exit();
        }
    }
}
